package cn.migu.music.hangupsms.service;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSON;

import cn.migu.music.common.utils.LogUtils;
import cn.migu.music.hangupsms.common.config.HangUpSmsDbConfig;
import cn.migu.music.hangupsms.common.entity.OperateBase;
import cn.migu.music.hangupsms.common.entity.SettingResponse;
import cn.migu.music.hangupsms.common.entity.SettingsChangeLog;
import cn.migu.music.hangupsms.repository.SettingsChangeLogMapper;
import lombok.extern.slf4j.Slf4j;

@RestController
@Slf4j
public class SettingsChangeLogService {
    private static final Map<String, SettingsApplyHandler> applyMap       = new HashMap<>();

    private static final Map<String, Field>                configFieldMap = new HashMap<>();

    private static final Map<String, String>               tableMap       = new HashMap<>();

    @Autowired
    private SettingsChangeLogMapper                  logMapper;
    @Autowired
    private HangUpSmsDbConfig                        hangUpSmsDbConfig;

    @PostConstruct
    public void init() {
        Field[] fs = HangUpSmsDbConfig.class.getDeclaredFields();
        for (Field field : fs) {
            configFieldMap.put(field.getName(), field);
        }
        tableMap.put("smsTemplate", "t_migu_hangup_sms_template");
        tableMap.put("smsSendFrequency", "t_migu_hangup_sms_send_frequency");
        tableMap.put("smsSendTime", "t_migu_hangup_sms_send_time");
        tableMap.put("smsProvinceSwitch", "t_migu_hangup_sms_province_switch");
    }

    public void registerApply(String bzName, SettingsApplyHandler settingsApplyHandler) {
        applyMap.put(bzName, settingsApplyHandler);
    }

    public void addLog(OperateBase operateBase, String table, String rowId, String currentContent, String historyContent) {
        SettingsChangeLog changeLog = new SettingsChangeLog();
        changeLog.setOperateTable(table);
        changeLog.setOperateRowId(rowId);
        changeLog.setOperateType(operateBase.getOperationEnum().getCode());
        changeLog.setCurrentContent(currentContent);
        changeLog.setHistoryContent(historyContent);
        changeLog.setOperateComment(operateBase.getOperateComment());
        changeLog.setOperateUser(operateBase.getOperateUser());
        logMapper.insert(changeLog);
    }

    /**
     * 挂机短信配置
     * 
     * @param txId
     *            字段信息
     * @param operationUser
     *            操作字段
     * @return
     */
    @GetMapping({ "/hangupsms/settings/apply/add/v1.0" })
    public SettingResponse<Void> applySettings(@RequestParam("txId") String txId, @RequestParam("operationUser") String operationUser) {
        SettingResponse<Void> response = new SettingResponse<>();
        if (StringUtils.isEmpty(txId)) {
            response.setResultCode(SettingResponse.ERROR_CODE);
            response.setResultMessage("txId is null or empty");
            return response;
        }
        String[] columns = txId.split("\\.");
        if (columns.length != 2) {
            response.setResultCode(SettingResponse.ERROR_CODE);
            response.setResultMessage("txId is invalid: length");
            return response;
        }
        SettingsApplyHandler handler = applyMap.get(columns[0]);
        if (handler == null) {
            response.setResultCode(SettingResponse.ERROR_CODE);
            response.setResultMessage("txId is invalid: handler is null");
            return response;
        }
        response.setResultCode(SettingResponse.ERROR_CODE);
        response.setResultMessage("failed");
        if (handler.apply(columns[1], operationUser)) {
            response.setResultCode(SettingResponse.SUCCESS_CODE);
            response.setResultMessage(SettingResponse.SUCCESS_MSG);
        }
        return response;
    }

    /**
     * 查询配置字段信息
     * 
     * @param settingName
     *            字段名称
     * @return
     */
    @GetMapping({ "/hangupsms/settings/apply/fetch/v1.0" })
    public String getTheCachedConfig(@RequestParam("settingName") String settingName) {
        Field field = configFieldMap.get(settingName);
        if (field == null) {
            return "no such setting";
        }
        try {
            Field accessField = hangUpSmsDbConfig.getClass().getDeclaredField(settingName);
            accessField.setAccessible(true);
            Object ob = accessField.get(hangUpSmsDbConfig);
            return JSON.toJSONString(ob);
        } catch (Exception e) {
            LogUtils.error(e, log, "error.");
            return "meet error:" + e.getMessage();
        }
    }

    /**
     * 日志查询接口
     * 
     * @param settingBiz
     *            表名
     * @param bizId
     *            行号
     * @param opType
     *            操作类型
     * @param pageIndex
     *            页数
     * @param pageSize
     *            条数
     * @return
     */
    @GetMapping({ "/hangupsms/settings/sms-settings-history/display/v1.0" })
    public SettingResponse<List<SettingsChangeLog>> getLogs(@RequestParam("settingBiz") String settingBiz,
                                                            @RequestParam("bizId") String bizId,
                                                            @RequestParam("opType") Integer opType,
                                                            @RequestParam("pageIndex") Integer pageIndex,
                                                            @RequestParam("pageSize") Integer pageSize) {
        SettingResponse<List<SettingsChangeLog>> response = new SettingResponse<>();
        String tableName = tableMap.get(settingBiz);
        if (StringUtils.isEmpty(tableName)) {
            response.setResultCode(SettingResponse.ERROR_CODE);
            response.setResultMessage("no such a biz");
            return response;
        }
        if (pageIndex == null || pageIndex <= 0) {
            pageIndex = 1;
        }
        if (pageSize == null || pageSize <= 0 || pageSize > 20) {
            pageSize = 20;
        }
        List<SettingsChangeLog> logList = logMapper.selectChangeLog(tableName, bizId, opType, (pageIndex - 1) * pageSize, pageSize);
        response.setData(logList);
        return response;
    }
}
